package com.wwh.Thread;
/*
 * 用实现的方式:
 * 模拟火车站售票窗口,开启三个窗口售票,总票数为100张
 * 
 * 此程序存在线程的安全问题:打印车票时会有重复票  , 0票 , 负数票
 * 1.线程安全问题存在的原因?
 * 	  由于线程在操作共享数据过程中,未执行完毕的情况下,另外的线程参与进来,导致共享数据存在了安全问题.
 * 
 * 2.如何来解决线程的安全问题?
 *   必须让一个线程操作共享数据完毕后,其他线程才有机会参与共享数据的操作.
 *   
 * 3.java如何实现线程安全,线程的同步机制
 * 	
 * 		方式一:同步代码块
 * 		synchronized(同步监视器){
 * 			//需要被同步的代码(造作共享数据的代码)
 * 		}
 * 		①共享数据:多个线程共同操作同一个数据
 * 		②同步监视器:由一个对象来充当.哪个线程获取此监视器,谁就执行大括号里被同步的代码,俗称:锁
 * 		要求:所有的线程必须共用同一把锁
 * 		注:在实现的方式中,考虑同步的化,可以使用this来充当锁,但是在继承的方式红,慎用this(考虑是否唯一,若唯一则可用)
 * 		方式二:
 * 
 */
class Windows1 implements Runnable{
	int ticket = 100;
	Object obj = new Object();
	Animal m = new Animal();
	public void run(){
		while(true){
			//参数也可直接写成this
			synchronized (obj) {
			//synchronized (this) {
			//synchronized (m) {
				if(ticket > 0){
					try {
						Thread.currentThread().sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + "售票为:" + ticket--);
				}else{
					break;
				}
			}
		}
	}
}

public class TestWindow4 {
	public static void main(String[] args) {
		Windows1 w = new Windows1();
		Thread t1 = new Thread(w);
		Thread t2 = new Thread(w);
		Thread t3 = new Thread(w);
		
		t1.setName("窗口1");
		t2.setName("窗口2");
		t3.setName("窗口3");
		
		t1.start();
		t2.start();
		t3.start();
	}
}

class Animal{}
